package org.xxpay.pay.channel.xkpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.DateUtils;
import org.xxpay.common.util.Util;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.common.util.str.StringUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.JsonUtil;
import org.xxpay.core.entity.TransOrder;
import org.xxpay.pay.channel.BaseTrans;
import org.xxpay.pay.channel.xkpay.util.XkBank;

import java.util.Date;
import java.util.Map;

@Service
public class XkTransService extends BaseTrans {

    private final static String logPrefix = "【XK代付】";

    // 下单地址
    public static final String ORDER_CREATE_STR = "/createXKPaid";
    // 查单地址
    private final static String ORDER_QUERY_STR = "/querypaid";
    // 余额查询地址
    private final static String ORDER_BALANCE_STR = "/queryBalance";


    @Override
    public String getChannelName() {
        return XkConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject balance(String payParam) {
        Map<String, Object> params = Maps.newHashMap();
        XkConfig xkConfig = new XkConfig(payParam);
        buildBalanceReqParams(params, xkConfig);
        String sign = getBalanceSign(params, xkConfig);
        params.put("sign", sign);
        _log.info("{}余额查询最终请求报文：{}", logPrefix, JSON.toJSONString(params));
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String origin = requestTemplate.postForObject(getReqUrl(xkConfig.getRequestUrl(), ORDER_BALANCE_STR), params, String.class);
        JSONObject resObject = JsonUtil.getObjectFromJson(origin, JSONObject.class);
        _log.info("{}余额查询响应参数：{}", logPrefix, JsonUtil.object2Json(resObject));
        JSONObject retObj = buildRetObj();
        retObj.put("cashBalance", Util.conversionYuanAmount(resObject.getLong("balance")));
        retObj.put("payBalance", Util.conversionYuanAmount(resObject.getLong("balance")));
        return retObj;
    }

    @Override
    public JSONObject trans(TransOrder transOrder) {
        Map<String, Object> params = Maps.newHashMap();
        XkConfig xkConfig = new XkConfig(getTransParam(transOrder));
        buildTransReqParams(params, transOrder, xkConfig);
        _log.info("{}申请代付请求参数：{}", logPrefix, params.toString());
        String sign = getTransOrderSign(params, xkConfig);
        params.put("sign", sign);
        _log.info("{}申请代付最终请求报文：{}", logPrefix, JSON.toJSONString(params));
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String origin = requestTemplate.postForObject(getReqUrl(xkConfig.getRequestUrl(), ORDER_CREATE_STR), params, String.class);
        JSONObject resObject = JsonUtil.getObjectFromJson(origin, JSONObject.class);
        _log.info("{}请求响应参数：{}", logPrefix, JsonUtil.object2Json(resObject));
        JSONObject retObj = buildRetObj();
        if (StringUtils.equals(resObject.getString("return_code"), "1")){
            retObj.put("transOrderId", transOrder.getTransOrderId());
            retObj.put("status", 1); // 1表示处理中
            retObj.put("isSuccess", true);
            return retObj;
        }
        retObj.put("status", 3);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "下单失败[" + resObject.getString("message") + "]");
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put("channelErrCode", resObject.getString("message"));
        retObj.put("isSuccess", false); // 3表示失败
        return retObj;
    }

    @Override
    public JSONObject query(TransOrder transOrder) {
        Map<String, Object> params = Maps.newHashMap();
        XkConfig xkConfig = new XkConfig(getTransParam(transOrder));
        buildQueryReqParams(params, transOrder, xkConfig);
        _log.info("{}查询请求参数：{}", logPrefix, JsonUtil.object2Json(params));
        String sign = getQuerySign(params, xkConfig);
        params.put("sign", sign);
        _log.info("{}查询最终请求报文：{}", logPrefix, JSON.toJSONString(params));

        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String origin = requestTemplate.postForObject(getReqUrl(xkConfig.getRequestUrl(), ORDER_QUERY_STR), params, String.class);
        JSONObject resObject = JsonUtil.getObjectFromJson(origin, JSONObject.class);
        _log.info("{}请求响应参数：{}", logPrefix, JsonUtil.object2Json(resObject));
        JSONObject retObj = new JSONObject();
        if(!org.apache.commons.lang3.StringUtils.equals(resObject.getString("return_code"), "-1")) {
            retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
            retObj.put("isSuccess", true);
            retObj.putAll(resObject);
            retObj.put("transOrderId", transOrder.getTransOrderId());
            String orderStatus = resObject.getString("resData");
            /**
             * 01-提现成功
             * 02-提现失败
             * 04-提现中
             */
            if (StringUtils.equals(orderStatus,"1")) {
                retObj.put("status", 2); // 2表示成功
            } else if (StringUtils.equals(orderStatus,"0")) {
                retObj.put("status", 3); // 3表示失败
            } else {
                retObj.put("status", 2); // 1处理中
            }
            retObj.put("channelObj", resObject);
            return retObj;
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, String.format("code:%s,desc:%s", resObject.getString("return_code"), resObject.getString("message")));
        retObj.put("channelErrCode", resObject.getString("message"));
        retObj.put("isSuccess", false);
        return retObj;
    }

    private void buildTransReqParams(Map<String, Object> params, TransOrder transOrder, XkConfig xkConfig){
        params.put("merchant_no", xkConfig.getMchId());
        params.put("pay_num", transOrder.getTransOrderId());
        params.put("total_fee", Util.conversionYuanAmount(transOrder.getAmount()));
        params.put("username", transOrder.getAccountName());
        params.put("bankcode", XkBank.valueOf(transOrder.getBankCode()).getCode());
        params.put("bankname", XkBank.valueOf(transOrder.getBankCode()).getName());
        params.put("subbranch", transOrder.getBankName());
        params.put("banknumber", transOrder.getAccountNo());
        params.put("notify_url", payConfig.getNotifyTransUrl(getChannelName()));
    }

    private void buildQueryReqParams(Map<String, Object> params, TransOrder transOrder, XkConfig xkConfig){
        params.put("merchant_no", xkConfig.getMchId());
        params.put("pay_num", transOrder.getTransOrderId());
        params.put("pay_way", 4);
    }

    private void buildBalanceReqParams(Map<String, Object> params, XkConfig xkConfig){
        params.put("merchant_no", xkConfig.getMchId());
        params.put("pay_way", 4);
    }

    private String getTransOrderSign(Map<String, Object> params, XkConfig xkConfig) {
        String text = String.valueOf(params.get("merchant_no"))
                +params.get("total_fee")
                +params.get("pay_num")
                +DateUtils.YYYYMMDD.format(new Date());
        return SignUtils.MD5.createSign(text, xkConfig.getPrivateKey(), SignUtils.CHARSET_UTF8).toUpperCase();
    }

    private String getQuerySign(Map<String, Object> params, XkConfig xkConfig) {
        String text = String.valueOf(params.get("merchant_no"))
                +params.get("pay_num")
                +DateUtils.YYYYMMDD.format(new Date());
        return SignUtils.MD5.createSign(text, xkConfig.getPrivateKey(), SignUtils.CHARSET_UTF8).toUpperCase();
    }

    private String getBalanceSign(Map<String, Object> params, XkConfig xkConfig) {
        String text = params.get("merchant_no")
                +DateUtils.YYYYMMDD.format(new Date());
        return SignUtils.MD5.createSign(text, xkConfig.getPrivateKey(), SignUtils.CHARSET_UTF8).toUpperCase();
    }

}
